﻿using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;

namespace ICodeShare.UI.Converters
{
    #region  IValueConverter
    /// <summary>
    /// String值转换成Visibility值
    /// </summary>
    /// <example>
    /// 1.引用该程序集，在xmal文件添加命名空间引用。
    ///   xmlns:cvts="http://schemas.extended.wpf.com/converters"
    /// 2.在xaml文件添加Resources。
    ///   <Window.Resources>
    ///   <cvts:StringToVisibilityConverter x:Key="cvtsStringToVisibility"/>
    ///   </Window.Resources>
    /// 3.在xaml文件中指定Binding值的Converter
    ///    <TextBox Text="{Binding ShowTheText,Converter={StaticResource cvtsStringToVisibility},ConverterParameter='是'}"></TextBox>
    ///    <TextBox Text="{Binding ShowTheText,Converter={StaticResource cvtsStringToVisibility},ConverterParameter='否;是'}"></TextBox>
    /// </example>
    /// <remarks>
    /// 参数parameter应该包含该一个参数或两个以分号(;)分隔的参数.
    /// 如果参数parameter包含两个字符串，第一个字符串表示条件为假的值，第二个字符串表示条件为真的值。.
    /// 如果参数parameter包含一个字符串，这个字符串则表示条件为真的值，条件为假的值用空字符串表示. 
    /// </remarks>
    [ValueConversion(typeof(String), typeof(Visibility))]
    public sealed class StringToVisibilityConverter : IValueConverter
    {
        #region Members
        /// <summary>
        /// 是否取相反值
        /// </summary>
        private bool _isInversed = false;
        /// <summary>
        /// 控件不可见时,如果条件为真则仍为控件分配位置，条件为假则不分配位置。
        /// </summary>
        private bool _useHidden = false;
        #endregion

        #region Construction
        /// <summary>
        /// 
        /// </summary>
        public StringToVisibilityConverter()
        {
        }

        /// <summary>
        /// 实例化一个BooleanToVisibilityConverter类
        /// </summary>
        /// <param name="isInversed">值相反</param>
        /// <param name="useHidden">是否为控件分配位置</param>
        public StringToVisibilityConverter(bool isInversed, bool useHidden)
        {
            this.IsInversed = isInversed;
            this.UseHidden = useHidden;
        }
        #endregion

        #region Properties
        /// <summary>
        /// 取反
        /// </summary>
        public bool IsInversed
        {
            get { return this._isInversed; }
            set { this._isInversed = value; }
        }

        /// <summary>
        /// 不可见时只隐藏
        /// </summary>
        public bool UseHidden
        {
            get { return this._useHidden; }
            set { this._useHidden = value; }
        }
        #endregion

        #region  Base Class Overrides 基类方法重写
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (!(value is Enum) && !(value is string))
            {
                return DependencyProperty.UnsetValue;
            }
            string falseValue, trueValue;
            ParseParameter(parameter, out falseValue, out trueValue);
            var result = System.Convert.ToString(value, CultureInfo.InvariantCulture).ToLower().Equals(trueValue.ToLower());

            if (this.IsInversed)
            {
                result = !result;
            }

            if (result)
            {
                return Visibility.Visible;
            }
            return this.UseHidden ? Visibility.Hidden : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (!(value is Visibility))
            {
                return DependencyProperty.UnsetValue;
            }

            string falseValue, trueValue;
            ParseParameter(parameter, out falseValue, out trueValue);

            var visibility = (Visibility)value;
            var result = (visibility == Visibility.Visible);
            if (this.IsInversed)
            {
                result = !result;
            }
            return result ? trueValue : falseValue;
        }
        #endregion

        #region Methods
        private void ParseParameter(object parameter, out string falseValue, out string trueValue)
        {
            falseValue = string.Empty;
            trueValue = string.Empty;
            var stringValue = parameter as string;
            if (string.IsNullOrWhiteSpace(stringValue))
                return;
            var stringValues = stringValue.Split(';');
            if (stringValues.Length == 0)
                return;

            if (stringValues.Length == 1)
            {
                trueValue = stringValues[0];
            }
            else
            {
                falseValue = stringValues[0];
                trueValue = stringValues[1];
            }
        }
        #endregion
    }
    #endregion
}
